﻿using System;
using System.Drawing;
using System.Globalization;
using System.Runtime.InteropServices;
using System.Text;

namespace LockWindows
{
    internal class Win32API
    {
        #region 常量

        public const int MF_REMOVE = 0x1000;
        public const int SC_RESTORE = 0xF120; //还原
        public const int SC_MOVE = 0xF010; //移动
        public const int SC_SIZE = 0xF000; //大小
        public const int SC_MINIMIZE = 0xF020; //最小化
        public const int SC_MAXIMIZE = 0xF030; //最大化
        public const int SC_CLOSE = 0xF060; //关闭
        public const int WM_SYSCOMMAND = 0x0112;
        public const int WM_COMMAND = 0x0111;
        public const int GW_HWNDFIRST = 0;
        public const int GW_HWNDLAST = 1;
        public const int GW_HWNDNEXT = 2;
        public const int GW_HWNDPREV = 3;
        public const int GW_OWNER = 4;
        public const int GW_CHILD = 5;
        public const int WM_NCCALCSIZE = 0x83;
        public const int WM_WINDOWPOSCHANGING = 0x46;
        public const int WM_PAINT = 0xF;
        public const int WM_CREATE = 0x1;
        public const int WM_NCCREATE = 0x81;
        public const int WM_NCPAINT = 0x85;
        public const int WM_PRINT = 0x317;
        public const int WM_DESTROY = 0x2;
        public const int WM_SHOWWINDOW = 0x18;
        public const int WM_SHARED_MENU = 0x1E2;
        public const int HC_ACTION = 0;
        public const int WH_CALLWNDPROC = 4;
        public const int GWL_WNDPROC = -4;
        public const int WS_SYSMENU = 0x80000;
        public const int WS_SIZEBOX = 0x40000;
        public const int WS_MAXIMIZEBOX = 0x10000;
        public const int WS_MINIMIZEBOX = 0x20000;

        #endregion 常量

        #region DLL导入

        //设置钩子
        [DllImport("user32.dll")]
        public static extern int SetWindowsHookEx(int idHook, LockWindows.Form1.HookProc lpfn, IntPtr hInstance, int threadID);

        //卸载钩子
        [DllImport("user32.dll", CallingConvention = CallingConvention.StdCall)]
        public static extern bool UnhookWindowsHookEx(int idHook);

        //调用下一个钩子
        [DllImport("user32.dll")]
        public static extern int CallNextHookEx(int idHook, int nCode, int wParam, IntPtr lParam);

        //返回当前线程ID值
        [DllImport("kernel32.dll")]
        public static extern int GetCurrentThreadId();

        //返回指定模块的句柄
        [DllImport("kernel32.dll")]
        public static extern IntPtr GetModuleHandle(string name);

        //函数作用：向INI文件中写信息
        [DllImport("kernel32.dll")]
        public static extern long WritePrivateProfileString(string section, string key, string val, string filePath);

        //设置窗体
        [DllImport("user32.dll")]
        public extern static bool SetWindowPos(IntPtr hWnd, int hWndInsertAfter, int X, int Y, int cx, int cy, uint uFlags);

        //函数作用：向INI文件中读信息
        [DllImport("kernel32.dll")]
        public static extern int GetPrivateProfileString(string section, string key, string def, StringBuilder retVal, int size, string filePath);

        //设置窗体显示在最前 的API：
        [DllImport("user32.dll", EntryPoint = "SetForegroundWindow")]
        public static extern bool SetForegroundWindow(IntPtr hWnd);

        //引入API函数，函数作用：将光标限制在矩形区域内
        [DllImport("user32.dll")]
        public static extern long ClipCursor(out Rectangle rec);

        /// <summary>
        /// 该函数改变指定窗口的属性．函数也将指定的一个32位值设置在窗口的额外存储空间的指定偏移位置。
        /// </summary>
        /// <param name="hWnd">窗口句柄</param>
        /// <param name="Index">指定将设定的大于等于0的偏移值。有效值的范围从0到额外类的存储空间的字节数减4：例如若指定了12位或多于12位的额外类存储空间，则应设为第三个32位整数的索引位8。要设置其他任何值，可以指定下面值之一：
        /// GWL_EXSTYLE：设定一个新的扩展风格。 　　
        /// GWL_STYLE：设定一个新的窗口风格。 　　
        /// GWL_WNDPROC：为窗口过程设定一个新的地址。 　　
        /// GWL_ID：设置一个新的窗口标识符。 　　
        /// GWL_HINSTANCE：设置一个新的应用程序实例句柄。 　　
        /// GWL_USERDATA：设置与窗口有关的32位值。每个窗口均有一个由创建该窗口的应用程序使用的32位值。 　　
        /// 当hWnd参数标识了一个对话框时，也可使用下列值： 　　
        /// DWL_DLGPROC：设置对话框过程的新地址。 　　
        /// DWL_MSGRESULT：设置在对话框过程中处理的消息的返回值。 　　
        /// DWL_USER：设置的应用程序私有的新的额外信息，例如一个句柄或指针。 　　
        /// dwNewLong：指定的替换值。 </param>
        /// <param name="Value">指定的替换值。</param>
        /// <returns>如果函数成功，返回值是指定的32位整数的原来的值。如果函数失败，返回值为0。</returns>
        [DllImport("user32.dll", CharSet = CharSet.Auto)]
        public static extern int SetWindowLong(IntPtr hWnd, int Index, int Value);

        [DllImport("user32.dll", CharSet = CharSet.Auto)]
        public static extern int GetWindowLong(IntPtr hWnd, int Index);

        [DllImport("user32")]
        public static extern IntPtr GetSystemMenu(IntPtr hwnd, int flag);

        [DllImport("user32")]
        public static extern int TrackPopupMenu(int hMenu, int wFlags, int x, int y, int nReserved, IntPtr hwnd, int lprc);

        /// <summary>
        /// 该函数将指定的消息发送到一个或多个窗口。此函数为指定的窗口调用窗口程序，直到窗口程序处理完消息再返回。而函数PostMessage不同，将一个消息寄送到一个线程的消息队列后立即返回。
        /// </summary>
        /// <param name="hwnd">其窗口程序将接收消息的窗口的句柄。</param>
        /// <param name="msg">指定被发送的消息。 </param>
        /// <param name="wp">指定附加的消息特定信息。 </param>
        /// <param name="lp">指定附加的消息特定信息。 </param>
        /// <returns></returns>
        [DllImport("user32")]
        public static extern int SendMessage(IntPtr hwnd, int msg, int wp, int lp);

        /// <summary>
        /// 该函数从当前线程中的窗口释放鼠标捕获，并恢复通常的鼠标输入处理。捕获鼠标的窗口接收所有的鼠标输入（无论光标的位置在哪里），除非点击鼠标键时，光标热点在另一个线程的窗口中。
        /// </summary>
        /// <returns>如果函数调用成功，返回非零值；如果函数调用失败，返回值是零。若想获得更多的错误信息，请调用GetlastError函数。 </returns>
        [DllImport("user32")]
        public static extern int ReleaseCapture();

        /// <summary>
        /// 创建一个圆角矩形，该矩形由X1，Y1-X2，Y2确定，并由X3，Y3确定的椭圆描述圆角弧度 返回值 Long，执行成功则为区域句柄，失败则为0
        /// </summary>
        /// <param name="x1">矩形左上角的X</param>
        /// <param name="y1">矩形左上角的Y</param>
        /// <param name="x2">矩形右下角的X</param>
        /// <param name="y2">矩形右下角的Y</param>
        /// <param name="x3">圆角椭圆的宽。其范围从0（没有圆角）到矩形宽（全圆） </param>
        /// <param name="y3">圆角椭圆的高。其范围从0（没有圆角）到矩形高（全圆） </param>
        /// <returns>If the function succeeds, the return value is the handle to the region. 　　If the function fails, the return value is NULL. </returns>
        [DllImport("gdi32.dll")]
        public static extern int CreateRoundRectRgn(int x1, int y1, int x2, int y2, int x3, int y3);

        [DllImport("user32.dll")]
        public static extern int SetWindowRgn(IntPtr hwnd, int hRgn, Boolean bRedraw);

        public const int CS_DROPSHADOW = 0x20000;

        [DllImport("user32.dll", CharSet = CharSet.Auto)]
        public static extern int SetClassLong(IntPtr hwnd, int nIndex, int dwNewLong);

        [DllImport("user32.dll", CharSet = CharSet.Auto)]
        public static extern int GetClassLong(IntPtr hwnd, int nIndex);

        public struct MENUINFO
        {
            public int cbSize;
            public uint fMask;
            public int dwStyle;
            public int cyMax;
            public int hbrBack;
            public int dwContextHelpID;
            public int dwMenuData;
        }

        [DllImport("gdi32")]
        public static extern int CreatePatternBrush(int hBitmap);
        /// <summary>
        /// 禁用鼠标
        /// </summary>
        /// <param name="status">隐藏参数值0; 显示1</param>
        [DllImport("user32.dll", EntryPoint = "ShowCursor", CharSet = CharSet.Auto)]
        public extern static void ShowCursor(int status);

        [DllImport("user32")]
        public static extern int SetMenuInfo(IntPtr hMenu, ref MENUINFO mi);

        [DllImport("user32.dll", EntryPoint = "ShowWindow", CharSet = CharSet.Auto)]
        public static extern int ShowWindow(IntPtr hwnd, int nCmdShow);

        [DllImport("kernel32.dll")]
        public static extern bool SetProcessWorkingSetSize(IntPtr process, int minSize, int maxSize);

        public const int GCW_ATOM = -32;
        public const int GCL_CBCLSEXTRA = -20;
        public const int GCL_CBWNDEXTRA = -18;
        public const int GCL_HBRBACKGROUND = -10;
        public const int GCL_HCURSOR = -12;
        public const int GCL_HICON = -14;
        public const int GCL_HMODULE = -16;
        public const int GCL_MENUNAME = -8;
        public const int GCL_STYLE = -26;
        public const int GCL_WNDPROC = -24;

        [DllImport("user32", EntryPoint = "GetClassLong")]
        public static extern int GetClassLong(int hwnd, int nIndex);

        [DllImport("user32", EntryPoint = "SetClassLong")]
        public static extern int SetClassLong(int hwnd, int nIndex, int dwNewLong);

        public const int WM_SETREDRAW = 0x000B;
        public const int WM_USER = 0x400;
        public const int EM_GETEVENTMASK = (WM_USER + 59);
        public const int EM_SETEVENTMASK = (WM_USER + 69);

        [DllImport("user32.dll")]
        public extern static bool LockWindowUpdate(IntPtr hWndLock);

        [DllImport("User32.dll", CharSet = CharSet.Auto)]
        public static extern IntPtr GetWindowDC(IntPtr handle);

        [DllImport("User32.dll", CharSet = CharSet.Auto)]
        public static extern IntPtr ReleaseDC(IntPtr handle, IntPtr hDC);

        [DllImport("Gdi32.dll", CharSet = CharSet.Auto)]
        public static extern IntPtr CreateCompatibleDC(IntPtr hdc);

        [DllImport("User32.dll", CharSet = CharSet.Auto)]
        public static extern int GetClassName(IntPtr hwnd, char[] className, int maxCount);

        [DllImport("User32.dll", CharSet = CharSet.Auto)]
        public static extern IntPtr GetWindow(IntPtr hwnd, int uCmd);

        [DllImport("User32.dll", CharSet = CharSet.Auto)]
        public static extern bool IsWindowVisible(IntPtr hwnd);

        [DllImport("user32", CharSet = CharSet.Auto)]
        public static extern int GetClientRect(IntPtr hwnd, ref RECT lpRect);

        [DllImport("user32", CharSet = CharSet.Auto)]
        public static extern int GetClientRect(IntPtr hwnd, [In, Out] ref Rectangle rect);

        [DllImport("user32", CharSet = CharSet.Auto)]
        public static extern bool MoveWindow(IntPtr hwnd, int X, int Y, int nWidth, int nHeight, bool bRepaint);

        [DllImport("user32", CharSet = CharSet.Auto)]
        public static extern bool UpdateWindow(IntPtr hwnd);

        [DllImport("user32", CharSet = CharSet.Auto)]
        public static extern bool InvalidateRect(IntPtr hwnd, ref Rectangle rect, bool bErase);

        [DllImport("user32", CharSet = CharSet.Auto)]
        public static extern bool ValidateRect(IntPtr hwnd, ref Rectangle rect);

        [DllImport("user32.dll", CharSet = CharSet.Auto)]
        public static extern bool GetWindowRect(IntPtr hWnd, [In, Out] ref Rectangle rect);

        [StructLayout(LayoutKind.Sequential)]
        public struct RECT
        {
            public int Left;
            public int Top;
            public int Right;
            public int Bottom;
        }

        [StructLayout(LayoutKind.Sequential)]
        public struct WINDOWPOS
        {
            public IntPtr hwnd;
            public IntPtr hwndAfter;
            public int x;
            public int y;
            public int cx;
            public int cy;
            public uint flags;
        }

        [StructLayout(LayoutKind.Sequential)]
        public struct NCCALCSIZE_PARAMS
        {
            public RECT rgc;
            public WINDOWPOS wndpos;
        }

        [StructLayout(LayoutKind.Sequential)]
        public struct tagSCROLLINFO
        {
            public uint cbSize;
            public uint fMask;
            public int nMin;
            public int nMax;
            public uint nPage;
            public int nPos;
            public int nTrackPos;
        }

        public enum fnBar
        {
            SB_HORZ = 0,
            SB_VERT = 1,
            SB_CTL = 2
        }

        public enum fMask
        {
            SIF_ALL,
            SIF_DISABLENOSCROLL = 0X0010,
            SIF_PAGE = 0X0002,
            SIF_POS = 0X0004,
            SIF_RANGE = 0X0001,
            SIF_TRACKPOS = 0X0008
        }

        public static int MakeLong(short lowPart, short highPart)
        {
            return (int)(((ushort)lowPart) | (uint)(highPart << 16));
        }

        public const int SB_THUMBTRACK = 5;
        public const int WM_HSCROLL = 0x114;
        public const int WM_VSCROLL = 0x115;

        [DllImport("user32.dll", EntryPoint = "GetScrollInfo")]
        public static extern bool GetScrollInfo(IntPtr hwnd, int fnBar, ref SCROLLINFO lpsi);

        [DllImport("user32.dll", EntryPoint = "SetScrollInfo")]
        public static extern int SetScrollInfo(IntPtr hwnd, int fnBar, [In] ref SCROLLINFO lpsi, bool fRedraw);

        [DllImport("User32.dll", CharSet = CharSet.Auto, EntryPoint = "SendMessage")]
        private static extern IntPtr SendMessage(IntPtr hWnd, uint Msg, IntPtr wParam, IntPtr lParam);

        [DllImport("user32.dll", SetLastError = true)]
        public static extern bool PostMessage(IntPtr hWnd, uint Msg, long wParam, int lParam);

        public struct SCROLLINFO
        {
            public uint cbSize;
            public uint fMask;
            public int nMin;
            public int nMax;
            public uint nPage;
            public int nPos;
            public int nTrackPos;
        }

        public enum ScrollInfoMask
        {
            SIF_RANGE = 0x1,
            SIF_PAGE = 0x2,
            SIF_POS = 0x4,
            SIF_DISABLENOSCROLL = 0x8,
            SIF_TRACKPOS = 0x10,
            SIF_ALL = SIF_RANGE + SIF_PAGE + SIF_POS + SIF_TRACKPOS
        }

        public enum ScrollBarDirection
        {
            SB_HORZ = 0,
            SB_VERT = 1,
            SB_CTL = 2,
            SB_BOTH = 3
        }

        [DllImport("user32.dll", CharSet = CharSet.Auto, ExactSpelling = true)]
        public static extern bool GetClientRect(HandleRef hWnd, [In, Out] ref RECT rect);

        [StructLayout(LayoutKind.Sequential)]
        public class SYSTEMTIME
        {
            public short wYear;
            public short wMonth;
            public short wDayOfWeek;
            public short wDay;
            public short wHour;
            public short wMinute;
            public short wSecond;
            public short wMilliseconds;

            public override string ToString()
            {
                return ("[SYSTEMTIME: " + this.wDay.ToString(CultureInfo.InvariantCulture) + "/" + this.wMonth.ToString(CultureInfo.InvariantCulture) + "/" + this.wYear.ToString(CultureInfo.InvariantCulture) + " " + this.wHour.ToString(CultureInfo.InvariantCulture) + ":" + this.wMinute.ToString(CultureInfo.InvariantCulture) + ":" + this.wSecond.ToString(CultureInfo.InvariantCulture) + "]");
            }
        }

        [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
        public class SYSTEMTIMEARRAY
        {
            public short wYear1;
            public short wMonth1;
            public short wDayOfWeek1;
            public short wDay1;
            public short wHour1;
            public short wMinute1;
            public short wSecond1;
            public short wMilliseconds1;
            public short wYear2;
            public short wMonth2;
            public short wDayOfWeek2;
            public short wDay2;
            public short wHour2;
            public short wMinute2;
            public short wSecond2;
            public short wMilliseconds2;
        }

        #endregion DLL导入

        #region 淡入淡出API例子

        //        using   System.Runtime.InteropServices;

        //private   void   Form2_Load(object   sender,   System.EventArgs   e)
        //{
        //Win32.AnimateWindow(this.Handle,500,   Win32.AW_BLEND);
        //}
        //public   class   Win32
        //{
        //public   const   Int32   AW_HOR_POSITIVE   =   0x00000001;
        //public   const   Int32   AW_HOR_NEGATIVE   =   0x00000002;
        //public   const   Int32   AW_VER_POSITIVE   =   0x00000004;
        //public   const   Int32   AW_VER_NEGATIVE   =   0x00000008;
        //public   const   Int32   AW_CENTER   =   0x00000010;
        //public   const   Int32   AW_HIDE   =   0x00010000;
        //public   const   Int32   AW_ACTIVATE   =   0x00020000;
        //public   const   Int32   AW_SLIDE   =   0x00040000;
        //public   const   Int32   AW_BLEND   =   0x00080000;
        //[DllImport( "user32.dll ",   CharSet=CharSet.Auto)]
        //public   static   extern   bool   AnimateWindow(
        //IntPtr   hwnd,   //   handle   to   window
        //int   dwTime,   //   duration   of   animation
        //int   dwFlags   //   animation   type
        //);
        //}
        //第一个 dwTime 是动画的时间，dwflag的取值如下这些
        //public const Int32 AW_HOR_POSITIVE = 0x00000001;   //从左到右显示
        //public const Int32 AW_HOR_NEGATIVE = 0x00000002;  //从右到左显示
        //public const Int32 AW_VER_POSITIVE = 0x00000004;   //从上到下显示
        //public const Int32 AW_VER_NEGATIVE = 0x00000008;  //从下到上显示
        //public const Int32 AW_CENTER = 0x00000010;         //若使用了AW_HIDE标志，则使窗口向内重叠，即收缩窗口；否则使窗口向外扩展，即展开窗口
        //public const Int32 AW_HIDE = 0x00010000;            //隐藏窗口，缺省则显示窗口
        //public const Int32 AW_ACTIVATE = 0x00020000;       //激活窗口。在使用了AW_HIDE标志后不能使用这个标志
        //public const Int32 AW_SLIDE = 0x00040000;           //使用滑动类型。缺省则为滚动动画类型。当使用AW_CENTER标志时，这个标志就被忽略
        //public const Int32 AW_BLEND = 0x00080000;          //透明度从高到低

        #endregion 淡入淡出API例子
    }
}